//! 增强类型检查器和类型推断系统
//!
//! 设计原则：
//! - 集成新的类型系统功能
//! - 支持类型转换和类型推断
//! - 提供更精确的类型检查
//! - 支持泛型和类型约束

use crate::ast::{ASTNode, SourceLocation};
use crate::errors::{CompilerError, ErrorKind};
use crate::interpreter::method::MethodType;
use crate::type_system::{
    ConversionCompatibility, ConversionUtils, TypeConverter, TypeHierarchy, TypeSystem,
};
use std::collections::HashMap;

/// 类型信息
#[derive(Debug, Clone, PartialEq)]
pub enum TypeInfo {
    /// 基础类型
    Basic(MethodType),
    /// 函数类型
    Function {
        params: Vec<TypeInfo>,
        return_type: Box<TypeInfo>,
    },
    /// 泛型类型
    Generic {
        name: String,
        constraints: Vec<TypeInfo>,
    },
    /// 联合类型
    Union(Vec<TypeInfo>),
    /// 未知类型（需要推断）
    Unknown,
}

impl TypeInfo {
    /// 转换为字符串表示
    pub fn to_string(&self) -> String {
        match self {
            TypeInfo::Basic(t) => format!("{:?}", t),
            TypeInfo::Function {
                params,
                return_type,
            } => {
                let params_str: Vec<String> = params.iter().map(|p| p.to_string()).collect();
                format!(
                    "函数({}) -> {}",
                    params_str.join(", "),
                    return_type.to_string()
                )
            }
            TypeInfo::Generic { name, .. } => name.clone(),
            TypeInfo::Union(types) => {
                let types_str: Vec<String> = types.iter().map(|t| t.to_string()).collect();
                types_str.join(" | ")
            }
            TypeInfo::Unknown => "未知".to_string(),
        }
    }

    /// 转换为MethodType
    pub fn to_method_type(&self) -> MethodType {
        match self {
            TypeInfo::Basic(t) => t.clone(),
            TypeInfo::Function { .. } => MethodType::Function,
            TypeInfo::Generic { .. } => MethodType::Generic,
            TypeInfo::Union(_) => MethodType::Generic,
            TypeInfo::Unknown => MethodType::Generic,
        }
    }
}

/// 类型环境（支持作用域）
pub struct TypeEnvironment {
    /// 类型映射
    types: HashMap<String, TypeInfo>,
    /// 父环境（用于作用域链）
    parent: Option<Box<TypeEnvironment>>,
    /// 是否是函数作用域
    is_function_scope: bool,
}

impl TypeEnvironment {
    /// 创建新的类型环境
    pub fn new() -> Self {
        Self {
            types: HashMap::new(),
            parent: None,
            is_function_scope: false,
        }
    }

    /// 创建子环境（新作用域）
    pub fn create_child(&self, is_function_scope: bool) -> Self {
        Self {
            types: HashMap::new(),
            parent: Some(Box::new(self.clone())),
            is_function_scope,
        }
    }

    /// 添加类型信息
    pub fn add_type(&mut self, name: String, type_info: TypeInfo) {
        self.types.insert(name, type_info);
    }

    /// 获取类型信息
    pub fn get_type(&self, name: &str) -> Option<TypeInfo> {
        if let Some(type_info) = self.types.get(name) {
            return Some(type_info.clone());
        }

        // 在父环境中查找
        if let Some(parent) = &self.parent {
            parent.get_type(name)
        } else {
            None
        }
    }

    /// 更新类型信息
    pub fn update_type(&mut self, name: String, type_info: TypeInfo) -> Result<(), String> {
        if self.types.contains_key(&name) {
            self.types.insert(name, type_info);
            Ok(())
        } else if let Some(parent) = &mut self.parent {
            parent.update_type(name, type_info)
        } else {
            Err(format!("未定义的标识符: {}", name))
        }
    }

    /// 克隆环境
    pub fn clone(&self) -> Self {
        Self {
            types: self.types.clone(),
            parent: self.parent.as_ref().map(|p| Box::new((*p).clone())),
            is_function_scope: self.is_function_scope,
        }
    }
}

/// 增强类型检查器结果
type TypeCheckResult<T> = Result<T, CompilerError>;

/// 增强类型检查器
pub struct EnhancedTypeChecker {
    /// 类型环境（支持作用域）
    env: TypeEnvironment,
    /// 错误列表
    errors: Vec<CompilerError>,
    /// 类型系统
    type_system: TypeSystem,
    /// 类型转换器
    type_converter: TypeConverter,
    /// 类型层次结构
    #[allow(dead_code)]
    type_hierarchy: TypeHierarchy,
    /// 函数返回类型栈（用于检查return语句）
    #[allow(dead_code)]
    return_type_stack: Vec<TypeInfo>,
    /// 循环深度（用于检查break/continue）
    #[allow(dead_code)]
    loop_depth: usize,
}

impl EnhancedTypeChecker {
    /// 创建增强类型检查器
    pub fn new() -> Self {
        let mut checker = Self {
            env: TypeEnvironment::new(),
            errors: Vec::new(),
            type_system: TypeSystem::new(),
            type_converter: TypeConverter::new(),
            type_hierarchy: TypeHierarchy::new(),
            return_type_stack: Vec::new(),
            loop_depth: 0,
        };

        // 初始化内置类型
        checker.initialize_builtin_types();
        checker
    }

    /// 初始化内置类型
    fn initialize_builtin_types(&mut self) {
        // 注册内置函数类型
        let builtin_functions = vec![
            (
                "书",
                TypeInfo::Function {
                    params: vec![TypeInfo::Basic(MethodType::String)],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Null)),
                },
            ),
            (
                "书行",
                TypeInfo::Function {
                    params: vec![TypeInfo::Basic(MethodType::String)],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Null)),
                },
            ),
            (
                "加",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Number),
                        TypeInfo::Basic(MethodType::Number),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Number)),
                },
            ),
            (
                "减",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Number),
                        TypeInfo::Basic(MethodType::Number),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Number)),
                },
            ),
            (
                "乘",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Number),
                        TypeInfo::Basic(MethodType::Number),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Number)),
                },
            ),
            (
                "除",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Number),
                        TypeInfo::Basic(MethodType::Number),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Number)),
                },
            ),
            (
                "等于",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Generic),
                        TypeInfo::Basic(MethodType::Generic),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Boolean)),
                },
            ),
            (
                "不等于",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Generic),
                        TypeInfo::Basic(MethodType::Generic),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Boolean)),
                },
            ),
            (
                "且",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Boolean),
                        TypeInfo::Basic(MethodType::Boolean),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Boolean)),
                },
            ),
            (
                "或",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::Boolean),
                        TypeInfo::Basic(MethodType::Boolean),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Boolean)),
                },
            ),
            (
                "非",
                TypeInfo::Function {
                    params: vec![TypeInfo::Basic(MethodType::Boolean)],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Boolean)),
                },
            ),
            (
                "长",
                TypeInfo::Function {
                    params: vec![TypeInfo::Basic(MethodType::String)],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Number)),
                },
            ),
            (
                "包含",
                TypeInfo::Function {
                    params: vec![
                        TypeInfo::Basic(MethodType::String),
                        TypeInfo::Basic(MethodType::String),
                    ],
                    return_type: Box::new(TypeInfo::Basic(MethodType::Boolean)),
                },
            ),
        ];

        for (name, type_info) in builtin_functions {
            self.env.add_type(name.to_string(), type_info);
        }
    }

    /// 检查AST
    pub fn check(&mut self, node: &ASTNode) -> TypeCheckResult<()> {
        self.check_node(node)
    }

    /// 检查节点
    fn check_node(&mut self, node: &ASTNode) -> TypeCheckResult<()> {
        match node {
            ASTNode::Program {
                preamble,
                body,
                epilogue,
                location: _,
            } => {
                for stmt in preamble {
                    self.check_node(stmt)?;
                }
                for stmt in body {
                    self.check_node(stmt)?;
                }
                for stmt in epilogue {
                    self.check_node(stmt)?;
                }
                Ok(())
            }

            ASTNode::VarDeclaration {
                name,
                value,
                location: _,
                type_name: _,
            } => {
                let value_type = self.infer_type(value)?;
                self.env.add_type(name.clone(), value_type);
                Ok(())
            }

            ASTNode::ConstDeclaration {
                name,
                value,
                location: _,
                type_name: _,
            } => {
                let value_type = self.infer_type(value)?;
                self.env.add_type(name.clone(), value_type);
                Ok(())
            }

            ASTNode::Assignment {
                name,
                value,
                location,
            } => {
                let value_type = self.infer_type(value)?;

                if let Some(var_type) = self.env.get_type(name) {
                    // 检查类型兼容性
                    if !self.is_type_compatible(&value_type, &var_type) {
                        // 尝试类型转换
                        if let Ok(converted_type) =
                            self.try_type_conversion(&value_type, &var_type, value)
                        {
                            // 更新环境
                            if let Err(err_msg) = self.env.update_type(name.clone(), converted_type)
                            {
                                return Err(CompilerError::simple(
                                    ErrorKind::TypeMismatch,
                                    err_msg,
                                ));
                            }
                        } else {
                            self.add_type_error(
                                location,
                                format!(
                                    "类型不匹配: 变量 {} 期望类型 {}, 得到类型 {}",
                                    name,
                                    var_type.to_string(),
                                    value_type.to_string()
                                ),
                            );
                        }
                    }
                } else {
                    // 未定义的变量，添加到环境
                    self.env.add_type(name.clone(), value_type);
                }
                Ok(())
            }

            // 其他节点类型将继续实现...
            _ => Ok(()),
        }
    }

    /// 推断类型
    fn infer_type(&mut self, node: &ASTNode) -> TypeCheckResult<TypeInfo> {
        match node {
            ASTNode::Number(_, _) => Ok(TypeInfo::Basic(MethodType::Number)),
            ASTNode::String(_, _) => Ok(TypeInfo::Basic(MethodType::String)),
            ASTNode::Boolean(_, _) => Ok(TypeInfo::Basic(MethodType::Boolean)),
            ASTNode::Null(_) => Ok(TypeInfo::Basic(MethodType::Null)),
            ASTNode::Array(elements, _) => {
                // 推断数组元素类型
                if elements.is_empty() {
                    Ok(TypeInfo::Basic(MethodType::List))
                } else {
                    let first_type = self.infer_type(&elements[0])?;

                    // 检查所有元素类型是否一致
                    for element in elements.iter().skip(1) {
                        let element_type = self.infer_type(element)?;
                        if !self.is_type_compatible(&element_type, &first_type) {
                            return Err(CompilerError::simple(
                                ErrorKind::TypeMismatch,
                                "数组元素类型不一致".to_string(),
                            ));
                        }
                    }

                    Ok(TypeInfo::Basic(MethodType::List))
                }
            }
            ASTNode::Identifier(name, _) => {
                if let Some(type_info) = self.env.get_type(name) {
                    Ok(type_info)
                } else {
                    Err(CompilerError::simple(
                        ErrorKind::UndefinedIdentifier,
                        format!("未定义的标识符: {}", name),
                    ))
                }
            }

            // 其他节点类型将继续实现...
            _ => Ok(TypeInfo::Basic(MethodType::Generic)),
        }
    }

    /// 尝试类型转换
    fn try_type_conversion(
        &mut self,
        from_type: &TypeInfo,
        to_type: &TypeInfo,
        _value: &ASTNode,
    ) -> Result<TypeInfo, String> {
        let from_method_type = from_type.to_method_type();
        let to_method_type = to_type.to_method_type();

        // 检查转换兼容性
        let compatibility = ConversionUtils::check_conversion_compatibility(
            &self.type_converter,
            &from_method_type,
            &to_method_type,
        );

        match compatibility {
            ConversionCompatibility::Compatible => Ok(to_type.clone()),
            ConversionCompatibility::Automatic => Ok(to_type.clone()),
            ConversionCompatibility::Explicit => {
                // 需要显式转换，这里可以添加转换建议
                Err(format!(
                    "需要显式转换: {} -> {}",
                    from_type.to_string(),
                    to_type.to_string()
                ))
            }
            ConversionCompatibility::Incompatible => Err(format!(
                "不兼容的类型转换: {} -> {}",
                from_type.to_string(),
                to_type.to_string()
            )),
        }
    }

    /// 检查类型兼容性
    fn is_type_compatible(&self, actual_type: &TypeInfo, expected_type: &TypeInfo) -> bool {
        match (actual_type, expected_type) {
            (TypeInfo::Basic(a), TypeInfo::Basic(e)) => {
                // 完全匹配
                if a == e {
                    return true;
                }

                // 检查类型转换支持
                let compatibility = ConversionUtils::check_conversion_compatibility(
                    &self.type_converter,
                    &a.clone(),
                    &e.clone(),
                );

                matches!(
                    compatibility,
                    ConversionCompatibility::Compatible | ConversionCompatibility::Automatic
                )
            }
            (TypeInfo::Function { .. }, TypeInfo::Function { .. }) => {
                // 函数类型兼容性检查（简化处理）
                true
            }
            (TypeInfo::Generic { .. }, _) => {
                // 泛型类型兼容性检查（简化处理）
                true
            }
            (_, TypeInfo::Generic { .. }) => {
                // 泛型类型兼容性检查（简化处理）
                true
            }
            (TypeInfo::Union(types), expected) => {
                // 联合类型兼容性检查
                types.iter().any(|t| self.is_type_compatible(t, expected))
            }
            (actual, TypeInfo::Union(types)) => {
                // 联合类型兼容性检查
                types.iter().any(|t| self.is_type_compatible(actual, t))
            }
            _ => false,
        }
    }

    /// 添加类型错误
    fn add_type_error(&mut self, location: &Option<SourceLocation>, message: String) {
        let error = if let Some(loc) = location {
            CompilerError::new(
                ErrorKind::TypeMismatch,
                message,
                "unknown".to_string(),
                loc.line,
                loc.column,
                "".to_string(),
            )
        } else {
            CompilerError::simple(ErrorKind::TypeMismatch, message)
        };
        self.errors.push(error);
    }

    /// 获取错误信息
    pub fn errors(&self) -> &[CompilerError] {
        &self.errors
    }

    /// 是否有错误
    pub fn has_errors(&self) -> bool {
        !self.errors.is_empty()
    }

    /// 获取类型环境
    pub fn get_environment(&self) -> &TypeEnvironment {
        &self.env
    }

    /// 获取类型系统
    pub fn get_type_system(&self) -> &TypeSystem {
        &self.type_system
    }

    /// 获取类型转换器
    pub fn get_type_converter(&self) -> &TypeConverter {
        &self.type_converter
    }
}

/// 类型推断引擎
pub struct TypeInferenceEngine {
    /// 类型约束
    constraints: Vec<TypeConstraint>,
    /// 类型环境
    env: TypeEnvironment,
}

/// 类型约束
#[derive(Debug, Clone)]
pub struct TypeConstraint {
    /// 约束类型
    pub constraint_type: ConstraintType,
    /// 涉及的变量
    pub variables: Vec<String>,
    /// 位置信息
    pub location: Option<SourceLocation>,
}

/// 约束类型
#[derive(Debug, Clone)]
pub enum ConstraintType {
    /// 相等约束
    Equal,
    /// 子类型约束
    Subtype,
    /// 可转换约束
    Convertible,
    /// 实例化约束
    InstanceOf,
}

impl TypeInferenceEngine {
    /// 创建新的类型推断引擎
    pub fn new() -> Self {
        Self {
            constraints: Vec::new(),
            env: TypeEnvironment::new(),
        }
    }

    /// 添加类型约束
    pub fn add_constraint(&mut self, constraint: TypeConstraint) {
        self.constraints.push(constraint);
    }

    /// 解决类型约束
    pub fn solve_constraints(&mut self) -> Result<HashMap<String, TypeInfo>, String> {
        let mut solutions = HashMap::new();

        // 简化的约束求解算法
        for constraint in &self.constraints {
            match &constraint.constraint_type {
                ConstraintType::Equal => {
                    // 处理相等约束
                    if constraint.variables.len() >= 2 {
                        let var1 = &constraint.variables[0];
                        let var2 = &constraint.variables[1];

                        if let (Some(type1), Some(type2)) =
                            (self.env.get_type(var1), self.env.get_type(var2))
                        {
                            if type1 == type2 {
                                solutions.insert(var1.clone(), type1.clone());
                                solutions.insert(var2.clone(), type2.clone());
                            }
                        }
                    }
                }
                ConstraintType::Convertible => {
                    // 处理可转换约束
                    // 这里可以添加更复杂的转换逻辑
                }
                _ => {
                    // 其他约束类型
                }
            }
        }

        Ok(solutions)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_enhanced_type_checker_creation() {
        let checker = EnhancedTypeChecker::new();

        // 检查内置函数是否正确注册
        let env = checker.get_environment();
        assert!(env.get_type("书").is_some());
        assert!(env.get_type("加").is_some());
        assert!(env.get_type("等于").is_some());
    }

    #[test]
    fn test_type_info_creation() {
        let basic_type = TypeInfo::Basic(MethodType::Number);
        assert_eq!(basic_type.to_string(), "Number");

        let function_type = TypeInfo::Function {
            params: vec![TypeInfo::Basic(MethodType::Number)],
            return_type: Box::new(TypeInfo::Basic(MethodType::String)),
        };
        assert_eq!(function_type.to_string(), "函数(Number) -> String");
    }

    #[test]
    fn test_type_environment() {
        let mut env = TypeEnvironment::new();

        // 添加类型
        env.add_type("x".to_string(), TypeInfo::Basic(MethodType::Number));
        env.add_type("y".to_string(), TypeInfo::Basic(MethodType::String));

        // 获取类型
        assert_eq!(env.get_type("x"), Some(TypeInfo::Basic(MethodType::Number)));
        assert_eq!(env.get_type("y"), Some(TypeInfo::Basic(MethodType::String)));
        assert_eq!(env.get_type("z"), None);

        // 创建子环境
        let mut child_env = env.create_child(false);
        child_env.add_type("z".to_string(), TypeInfo::Basic(MethodType::Boolean));

        // 子环境应该能访问父环境的变量
        assert_eq!(
            child_env.get_type("x"),
            Some(TypeInfo::Basic(MethodType::Number))
        );
        assert_eq!(
            child_env.get_type("z"),
            Some(TypeInfo::Basic(MethodType::Boolean))
        );
    }

    #[test]
    fn test_type_inference_engine() {
        let mut engine = TypeInferenceEngine::new();

        // 添加约束
        let constraint = TypeConstraint {
            constraint_type: ConstraintType::Equal,
            variables: vec!["x".to_string(), "y".to_string()],
            location: None,
        };
        engine.add_constraint(constraint);

        // 解决约束
        let solutions = engine.solve_constraints().unwrap();
        assert!(solutions.is_empty()); // 简化实现返回空结果
    }
}
